Printing and checking the WOLF tree

The wolf tree is a powerful data structure where all the problem is organized.

You can print it on the Terminal with different levels of detail, which are customizable through the API.

This gives you the opportunity to look at how WOLF is book-keeping all the information. You can use it to debug your developments, or to tune your algorithms.

Similarly, we have a method check that performs a thorough check of all the pointers in the tree to ensure that every node is properly connected.

The method Problem::print()

The method to call resides in Problem:

class Problem [...]
{

public:
   /**
    * \brief print wolf tree
    * \param depth :        levels to show ( 0: H, T, M : 1: H:S, T:F, M:L ; 2: H:S:p, T:F:C ; 3: T:F:C:f ; 4: T:F:C:f:c )
    * \param constr_by:     show factors pointing to F, f and L.
    * \param metric :       show metric info (status, time stamps, state vectors, measurements)
    * \param state_blocks : show state blocks
    */
   void print(int  depth            = 4,
              bool constr_by        = false,
              bool metric           = true,
              bool state_blocks     = false,
              std::ostream& stream  = std::cout) const;
}

The inlined documentation is enough for an API recall.

For a complete demonstration of how print(...) works, read on.

The input parameters of print() are documented as follows

  1. depth: The depth of the printed result.

  2. constr_by: print which factors point to each node of the tree

  3. metric: print metric values for all states and measurements

  4. state_blocks: print information about each state block individually

In order to correctly interpret the outcome, you just need to know a few mnemotechnics to identify the nodes:

  • P : Problem

  • H : Hardware

  • T : Trajectory

  • M : Map

  • S, Sen: Sensor

  • p, Prc: Processor

  • F, Frm: Frame

  • C, Cap: Capture

  • f, Ftr: Feature

  • c, Fac: Factor

Examples

Simplest print

print(0,0,0,0);

Even with such a short print, we see that we have two sensors, two frames and four landmarks:

Wolf tree status ------------------------
Hardware   -- 2S
Trajectory -- 2F
Map        -- 4L
-----------------------------------------

First level depth

print(1,0,0,0);

We start seeing some detail:

  • Each sensor has a type and name, and has one processor.

  • The frame structure is POV, and we have their time stamps, and how many Captures each.

  • We also see the type of landmarks.

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA" -- 1p
  Sen2 SensorImu "IMU" -- 1p
Trajectory
  Frm1 POV ts = 0.000000000 -- 3C
  Frm8 POV ts = 0.300000000 -- 1C
Map
  Lmk50 LandmarkApriltag
  Lmk52 LandmarkApriltag
  Lmk54 LandmarkApriltag
  Lmk56 LandmarkApriltag
-----------------------------------------

Second level depth

print(2,0,0,0);

The tree details are growing!

  • We see some status of the processors, with the origin and last captures, and to which frame they are attached.

  • We see the size of the motion data buffer in captures of type CaptureMotion.

  • We see the number of features of each capture.

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap71 -  Frm8
      l: Cap128 -  Frm13
  Sen2 SensorImu "IMU"
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap85 -   Frm8
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000
    Cap2 CaptureVoid ts = 0.000000000 -> Sen- -- 3f
    CapM3 CaptureImu ts = 0.000000000 -> Sen2 -- 0f
      buffer size  :  0
    Cap9 CaptureImage ts = 0.000000000 -> Sen1 -- 0f
  Frm8 POV ts = 0.300000000
    Cap71 CaptureImage ts = 0.300000000 -> Sen1 -- 4f
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 -- 1f
      buffer size  :  62 ; nbr of data samples : 61
Map
  Lmk50 LandmarkApriltag
  Lmk52 LandmarkApriltag
  Lmk54 LandmarkApriltag
  Lmk56 LandmarkApriltag
-----------------------------------------

Full depth

Let us show the full tree structure

print(4,0,0,0);

Now we see all the way down to the Features and Factors!

  • For each Feature, we can see the track it has been associated to

  • For each Factor, we see after the arrow --> the nodes it is pointing to.

    • Some Factors do not point anywhere, because they are absolute. We mark this with Abs.

  • Of course, you can also print(3,0,0,0) and stop at the Feature level.

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap71 -  Frm8
      l: Cap83 -  Frm9
  Sen2 SensorImu "IMU"
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap85 -   Frm8
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000
    Cap2 CaptureVoid ts = 0.000000000 -> Sen-
      Ftr1 trk0 Prior V
        Fac1 FactorBlockAbsolute --> Abs
      Ftr2 trk0 Prior O
        Fac2 FactorQuaternionAbsolute --> Abs
      Ftr3 trk0 Prior P
        Fac3 FactorBlockAbsolute --> Abs
    CapM3 CaptureImu ts = 0.000000000 -> Sen2
      buffer size  :  0
    Cap9 CaptureImage ts = 0.000000000 -> Sen1
  Frm8 POV ts = 0.300000000
    Cap71 CaptureImage ts = 0.300000000 -> Sen1
      Ftr24 trk50 FeatureApriltag
        Fac4 FactorApriltag --> Lmk50
      Ftr25 trk52 FeatureApriltag
        Fac5 FactorApriltag --> Lmk52
      Ftr26 trk54 FeatureApriltag
        Fac6 FactorApriltag --> Lmk54
      Ftr27 trk56 FeatureApriltag
        Fac7 FactorApriltag --> Lmk56
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1
      buffer size  :  62 ; nbr of data samples : 61
      Ftr32 trk0 FeatureImu
        Fac8 FactorImu --> Frm1 Cap3
Map
  Lmk50 LandmarkApriltag
  Lmk52 LandmarkApriltag
  Lmk54 LandmarkApriltag
  Lmk56 LandmarkApriltag
-----------------------------------------

Metric information

Let us add the metric information for states and measurements

print(3,0,1,0);

We now see the state values of:

  • Sensors: extrinsic and intrinsic parameters

  • Frames: robot position, orientation and velocity

  • Captures: in those of type IMU, the intrinsic sensor values, that is, the time-varying IMU biases!

  • Landmarks: position and orientation

Also,

  • the measurements contained in each Feature!

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    Fix,  x = (   0   0   0   0   0   0   1 320 240 320 320 )
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap71 -  Frm8
      l: Cap83 -  Frm9
  Sen2 SensorImu "IMU"
    Est,  x = ( 0 0 0 0 0 0 1 0 0 0 0 0 0 )
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap85 -   Frm8
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000
    Est,  x = ( 0 0 0 1 0 0 0 0 0 0 )
    Cap2 CaptureVoid ts = 0.000000000 -> Sen-
      Ftr1 trk0 Prior V -- 1c
        m = ( 0 0 0 )
      Ftr2 trk0 Prior O -- 1c
        m = ( 1 0 0 0 )
      Ftr3 trk0 Prior P -- 1c
        m = ( 0 0 0 )
    CapM3 CaptureImu ts = 0.000000000 -> Sen2
      Est,   x = ( 0 0 0 0 0 0 )
      buffer size  :  0
    Cap9 CaptureImage ts = 0.000000000 -> Sen1
  Frm8 POV ts = 0.300000000
    Est,  x = ( 0.000343 -0.00354 1.11e-16        1        0        0        0  0.00339  -0.0235 8.88e-16 )
    Cap71 CaptureImage ts = 0.300000000 -> Sen1
      Ftr24 trk50 FeatureApriltag -- 1c
        m = ( 0.046   0.6     1     0     0     0     1 )
      Ftr25 trk52 FeatureApriltag -- 1c
        m = (    0.046    0.097        1  7.4e-07 -2.6e-07 -3.4e-08        1 )
      Ftr26 trk54 FeatureApriltag -- 1c
        m = (     0.55    0.097        1  1.2e-07  8.7e-08 -6.8e-08        1 )
      Ftr27 trk56 FeatureApriltag -- 1c
        m = (     0.55     -0.4        1  7.1e-08  5.2e-08 -3.9e-08        1 )
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1
      Est,   x = ( 0 0 0 0 0 0 )
      buffer size  :  62 ; nbr of data samples : 61
      delta preint : (0.000343  0.00354   -0.441        0        0        0        1  0.00339   0.0235    -2.94)
      Ftr32 trk0 FeatureImu -- 1c
        m = ( 0.00034  0.0035   -0.44       0       0       0       1  0.0034   0.024    -2.9 )
Map
  Lmk50 LandmarkApriltag
    Est,  x = ( 0.0465 -0.597     -1      1      0      0      0 )
  Lmk52 LandmarkApriltag
    Est,  x = (   0.0465  -0.0971       -1        1 3.44e-08 -2.6e-07 -7.4e-07 )
  Lmk54 LandmarkApriltag
    Est,  x = (     0.546   -0.0971        -1         1   6.8e-08   8.7e-08 -1.25e-07 )
  Lmk56 LandmarkApriltag
    Est,  x = (     0.546     0.403        -1         1  3.86e-08  5.21e-08 -7.06e-08 )
-----------------------------------------

State blocks structure

Let us explore such states deeper, by showing the structure of state-blocks:

print(2,0,0,1);

All the state structure is now clearly displayed, showing the semantinc meaning of each part:

  • P: position

  • O: orientation

  • V: velocity

  • I: intrinsic parameters –> IMU biases

We can see the role of each state block in the estimation

  • [Est] means the block is estimated

  • [Fix] means the block is fixed

Also, we see the address value of the pointer to each state block. This might be useful to debug the interface with the solver, which might be using such pointers.

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    sb:    P [Fix] @ 0x5603407aaae0    O [Fix] @ 0x5603407abf50    I [Fix] @ 0x5603407ab8e0
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap72 -  Frm8
      l: Cap117 -  Frm12
  Sen2 SensorImu "IMU"
    sb:    P [Fix] @ 0x5603407ab160    O [Fix] @ 0x5603407ab0a0    I [Est] @ 0x560340e85690
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap85 -   Frm8
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000
    sb:    P [Est] @ 0x56034076f6a0    O [Est] @ 0x560340771c70    V [Est] @ 0x560340773560
    Cap2 CaptureVoid ts = 0.000000000 -> Sen- -- 3f
    CapM3 CaptureImu ts = 0.000000000 -> Sen2 -- 0f
      sb:    I [Est] @ 0x56034076c760
      buffer size  :  0
    Cap8 CaptureImage ts = 0.000000000 -> Sen1 -- 3f
  Frm8 POV ts = 0.300000000
    sb:    P [Est] @ 0x7ff7d00267d0    O [Est] @ 0x7ff7b0016540    V [Est] @ 0x7ff7c001f540
    Cap72 CaptureImage ts = 0.300000000 -> Sen1 -- 4f
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 -- 1f
      sb:    I [Est] @ 0x560340e85690
      buffer size  :  62 ; nbr of data samples : 61
Map
  Lmk50 LandmarkApriltag
    sb:    P [Est] @ 0x7ff7c001e3d0    O [Est] @ 0x56034077c140
  Lmk54 LandmarkApriltag
    sb:    P [Est] @ 0x560340769040    O [Est] @ 0x56034077c2f0
  Lmk56 LandmarkApriltag
    sb:    P [Est] @ 0x560340e84810    O [Est] @ 0x560340e853d0
  Lmk52 LandmarkApriltag
    sb:    P [Est] @ 0x7ff7d00254b0    O [Est] @ 0x7ff7a80227e0
-----------------------------------------

We can also combine state_block and metric options, and observe the state-block structure alongside the state values,

print(2,0,1,1);

which results in

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    P [Fix] = ( 0 0 0 ) @ 0x5633405c0c80
    O [Fix] = ( 0 0 0 1 ) @ 0x5633405c20f0
    I [Fix] = ( 320 240 320 320 ) @ 0x5633405c1a80
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap71 -  Frm8
      l: Cap128 -  Frm13
  Sen2 SensorImu "IMU"
    P [Fix] = ( 0 0 0 ) @ 0x5633405c1300
    O [Fix] = ( 0 0 0 1 ) @ 0x5633405c1240
    I [Est] = (  3.77e-08  3.76e-07  3.84e-11 -2.13e-06  2.13e-07  7.13e-07 ) @ 0x563340bc1830
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap85 -   Frm8
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000
    P [Est] = ( -2.67e-17  2.66e-16  3.76e-21 ) @ 0x563340585900
    O [Est] = (        1 3.61e-13 9.17e-12 9.15e-11 ) @ 0x563340587ed0
    V [Est] = ( -1.26e-09  1.26e-08  1.03e-13 ) @ 0x5633405897c0
    Cap2 CaptureVoid ts = 0.000000000 -> Sen- -- 3f
    CapM3 CaptureImu ts = 0.000000000 -> Sen2 -- 0f
      I [Est] = (  3.77e-08  3.76e-07  3.84e-11 -2.13e-06  2.13e-07  7.13e-07 ) @ 0x5633405829c0
      buffer size  :  0
    Cap9 CaptureImage ts = 0.000000000 -> Sen1 -- 0f
  Frm8 POV ts = 0.300000000
    P [Est] = (  0.000343  -0.00354 -7.41e-10 ) @ 0x563340c928d0
    O [Est] = (         1  1.07e-07  -3.2e-08 -3.19e-07 ) @ 0x7f27f8011ec0
    V [Est] = (   0.00339   -0.0235 -7.49e-09 ) @ 0x7f27f401bd70
    Cap71 CaptureImage ts = 0.300000000 -> Sen1 -- 4f
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1 -- 1f
      I [Est] = (  3.77e-08  3.76e-07  3.84e-11 -2.13e-06  2.13e-07  7.13e-07 ) @ 0x563340bc1830
      buffer size  :  62 ; nbr of data samples : 61
      delta preint : (0.000343  0.00354   -0.441        0        0        0        1  0.00339   0.0235    -2.94)
Map
  Lmk50 LandmarkApriltag
    P [Est] = ( 0.0468   -0.6     -1 ) @ 0x7f2804024f70
    O [Est] = (         1  1.07e-07  -3.2e-08 -3.19e-07 ) @ 0x563340c91750
  Lmk52 LandmarkApriltag
    P [Est] = ( 0.0468   -0.1     -1 ) @ 0x56334059a3c0
    O [Est] = (         1  1.41e-07 -2.92e-07 -1.06e-06 ) @ 0x563340c91650
  Lmk54 LandmarkApriltag
    P [Est] = ( 0.547  -0.1    -1 ) @ 0x7f2804022050
    O [Est] = (         1  1.75e-07   5.5e-08 -4.43e-07 ) @ 0x7f27f0002bc0
  Lmk56 LandmarkApriltag
    P [Est] = ( 0.547   0.4    -1 ) @ 0x563340be9810
    O [Est] = (        1 1.46e-07 2.01e-08 -3.9e-07 ) @ 0x5633401f0060
-----------------------------------------

Factors connectivity

Now let us show how Factors point to different nodes of the tree:

print(4,1,0,0);

We observe this information in two ways:

  • From each Factor, we see an outgoing arrow --> pointing to each node of the tree that concerns it.

    • Factors can point to Sensors, Frames, Captures, Features and Landmarks.

    • Some factors do not point anywhere, because they are absolute. We mark it with Abs.

  • To each node of the tree, we see an incoming arrow <-- with all Factors pointing to it.

    Logically, we want these correspondences to match in all cases:

    • If a factor Fac points to a node N, Fac --> N, then also N needs to be pointed by Fac, N <-- Fac.

    • Also, some nodes are not yet pointed by any factor. We see a dangling <-- arrow.

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap205 -  Frm20
      l: Cap216 -  Frm21
  Sen2 SensorImu "IMU"
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap218 -   Frm20
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000  <-- Fac8
    Cap2 CaptureVoid ts = 0.000000000 -> Sen-  <--
      Ftr1 trk0 Prior V -- 1c    <--
      Ftr2 trk0 Prior O -- 1c    <--
      Ftr3 trk0 Prior P -- 1c    <--
    CapM3 CaptureImu ts = 0.000000000 -> Sen2  <-- Fac8
      buffer size  :  0
    Cap9 CaptureImage ts = 0.000000000 -> Sen1  <--
  Frm8 POV ts = 0.300000000  <-- Fac13
    Cap71 CaptureImage ts = 0.300000000 -> Sen1  <--
      Ftr24 trk50 FeatureApriltag -- 1c    <--
      Ftr25 trk52 FeatureApriltag -- 1c    <--
      Ftr26 trk54 FeatureApriltag -- 1c    <--
      Ftr27 trk56 FeatureApriltag -- 1c    <--
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1  <-- Fac13
      buffer size  :  62 ; nbr of data samples : 61
      Ftr32 trk0 FeatureImu -- 1c    <--
  Frm14 POV ts = 0.600000000  <-- Fac18
    Cap140 CaptureImage ts = 0.600000000 -> Sen1  <--
      Ftr49 trk50 FeatureApriltag -- 1c    <--
      Ftr50 trk52 FeatureApriltag -- 1c    <--
      Ftr51 trk54 FeatureApriltag -- 1c    <--
      Ftr52 trk56 FeatureApriltag -- 1c    <--
    CapM152 CaptureImu ts = 0.600000000 -> Sen2 -> Origin: Cap85 ; Frm8  <-- Fac18
      buffer size  :  61 ; nbr of data samples : 60
      Ftr57 trk0 FeatureImu -- 1c    <--
  Frm20 POV ts = 0.900000000  <--
    Cap205 CaptureImage ts = 0.900000000 -> Sen1  <--
      Ftr74 trk50 FeatureApriltag -- 1c    <--
      Ftr75 trk52 FeatureApriltag -- 1c    <--
      Ftr76 trk54 FeatureApriltag -- 1c    <--
      Ftr77 trk56 FeatureApriltag -- 1c    <--
    CapM218 CaptureImu ts = 0.900000000 -> Sen2 -> Origin: Cap152 ; Frm14  <--
      buffer size  :  61 ; nbr of data samples : 60
      Ftr82 trk0 FeatureImu -- 1c    <--
Map
  Lmk50 LandmarkApriltag   <-- Fac4    Fac9  Fac14
  Lmk52 LandmarkApriltag   <-- Fac5    Fac10    Fac15
  Lmk54 LandmarkApriltag   <-- Fac6    Fac11    Fac16
  Lmk56 LandmarkApriltag   <-- Fac7    Fac12    Fac17
-----------------------------------------

Full print

Let us finally activate all options!

print(4,1,1,1);

A full print might be overwhelming!

Wolf tree status ------------------------
Hardware
  Sen1 SensorCamera "CAMERA"
    P [Fix] = ( 0 0 0 ) @ 0x55e3cb82dc80
    O [Fix] = ( 0 0 0 1 ) @ 0x55e3cb82f0f0
    I [Fix] = ( 320 240 320 320 ) @ 0x55e3cb82ea80
    PrcT1 ProcessorTrackerLandmarkApriltag "APRILTAG PROC"
      o: Cap71 -  Frm8
      l: Cap83 -  Frm9
  Sen2 SensorImu "IMU"
    P [Fix] = ( 0 0 0 ) @ 0x55e3cb82e300
    O [Fix] = ( 0 0 0 1 ) @ 0x55e3cb82e240
    I [Est] = ( 0 0 0 0 0 0 ) @ 0x55e3cbe2e110
    PrcM2 ProcessorImu "IMU PROC"
      o: Cap85 -   Frm8
      l: Cap4 -  Frm2
Trajectory
  Frm1 POV ts = 0.000000000  <-- Fac8
    P [Est] = ( 0 0 0 ) @ 0x55e3cb7f2900
    O [Est] = ( 1 0 0 0 ) @ 0x55e3cb7f4ed0
    V [Est] = ( 0 0 0 ) @ 0x55e3cb7f67c0
    Cap2 CaptureVoid ts = 0.000000000 -> Sen-  <--
      Ftr1 trk0 Prior V  <--
        m = ( 0 0 0 )
        Fac1 FactorBlockAbsolute --> Abs
      Ftr2 trk0 Prior O  <--
        m = ( 1 0 0 0 )
        Fac2 FactorQuaternionAbsolute --> Abs
      Ftr3 trk0 Prior P  <--
        m = ( 0 0 0 )
        Fac3 FactorBlockAbsolute --> Abs
    CapM3 CaptureImu ts = 0.000000000 -> Sen2  <-- Fac8
      I [Est] = ( 0 0 0 0 0 0 ) @ 0x55e3cb7ef9c0
      buffer size  :  0
    Cap10 CaptureImage ts = 0.000000000 -> Sen1  <--
  Frm8 POV ts = 0.300000000  <--
    P [Est] = ( 0.000343 -0.00354 1.11e-16 ) @ 0x55e3cbeff930
    O [Est] = ( 1 0 0 0 ) @ 0x7fdfd001efd0
    V [Est] = (  0.00339  -0.0235 8.88e-16 ) @ 0x7fdfd8010350
    Cap71 CaptureImage ts = 0.300000000 -> Sen1  <--
      Ftr24 trk50 FeatureApriltag  <--
        m = ( 0.046   0.6     1     0     0     0     1 )
        Fac4 FactorApriltag --> Lmk50
      Ftr25 trk52 FeatureApriltag  <--
        m = (    0.046    0.097        1  7.4e-07 -2.6e-07 -3.4e-08        1 )
        Fac5 FactorApriltag --> Lmk52
      Ftr26 trk54 FeatureApriltag  <--
        m = (     0.55    0.097        1  1.2e-07  8.7e-08 -6.8e-08        1 )
        Fac6 FactorApriltag --> Lmk54
      Ftr27 trk56 FeatureApriltag  <--
        m = (     0.55     -0.4        1  7.1e-08  5.2e-08 -3.9e-08        1 )
        Fac7 FactorApriltag --> Lmk56
    CapM85 CaptureImu ts = 0.300000000 -> Sen2 -> Origin: Cap3 ; Frm1  <--
      I [Est] = ( 0 0 0 0 0 0 ) @ 0x55e3cbe2e110
      buffer size  :  62 ; nbr of data samples : 61
      delta preint : (0.000343  0.00354   -0.441        0        0        0        1  0.00339   0.0235    -2.94)
      Ftr32 trk0 FeatureImu  <--
        m = ( 0.00034  0.0035   -0.44       0       0       0       1  0.0034   0.024    -2.9 )
        Fac8 FactorImu --> Frm1 Cap3
Map
  Lmk50 LandmarkApriltag   <-- Fac4
    P [Est] = ( 0.0465 -0.597     -1 ) @ 0x7fdfb001bd70
    O [Est] = ( 1 0 0 0 ) @ 0x7fdfb8023c40
  Lmk52 LandmarkApriltag   <-- Fac5
    P [Est] = (  0.0465 -0.0971      -1 ) @ 0x7fdfe0010880
    O [Est] = (        1 3.44e-08 -2.6e-07 -7.4e-07 ) @ 0x55e3cbefe310
  Lmk54 LandmarkApriltag   <-- Fac6
    P [Est] = (   0.546 -0.0971      -1 ) @ 0x55e3cb806a70
    O [Est] = (         1   6.8e-08   8.7e-08 -1.25e-07 ) @ 0x7fdfb8022050
  Lmk56 LandmarkApriltag   <-- Fac7
    P [Est] = ( 0.546 0.403    -1 ) @ 0x55e3cbe56990
    O [Est] = (         1  3.86e-08  5.21e-08 -7.06e-08 ) @ 0x55e3cb45ce30
---------------------------------------------------------------------

The method Problem::check()

The check() tool is intended for developers, and especially for developers involved in the core module of WOLF.

However, if you are writing plugins, you may want to ensure that what you do is fine in terms of the integrity of the WOLF tree.

We offer the method check() and a convenient alias, both in Problem:

class Problem [...]
{

public:
   // check the WOLF tree integrity
   bool check(bool verbose, std::ostream& stream) const;

   // alias
   bool check(int verbose_level = 0) const
   {
      return check((_verbose_level > 0), std::cout);
   }
}

This method is similar to print() in some aspects, but its main goal is to check that all pointers in the WOLF tree are valid and that the bidirectional property is satisfied: if A points to B, then B needs to also point to A.

So far, only two basic verbosity levels are implemented:

  • With verbose > 0 the method checks for pointer correctness and prints a pointer-oriented version of the whole WOLF tree for reference.

  • With verbose = 0 the method just checks tree integrity, printing nothing.

In case the check is not passed, error messages will be created to help identifying the issue.

Examples

Quiet check

ProblemPtr problem_ptr;

[... fill in the tree ...]

if (not problem_ptr->check(0))
   ERROR("There is something odd in Problem!");

Verbose check

ProblemPtr problem_ptr;

[... fill in the tree ...]

problem_ptr->check(1);

The result may look something like this, where:

  • The pointer of every WOLF node is shown.

  • The pointer of every state-block is shown, with the pointer of its local parametrization (see state block).

  • For every node, we check the pointers up in the tree (all ancestors).

  • For every factor, we check that the state blocks pointed at exist in the nodes pointed at.

  • All checks are bi-directional: if A has a pointer to B, then B must have a pointer to A, A <--> B.

    • One exception is that state blocks are pointed, but they do not point anywhere, N --> sb.

    • The second exception is that Captures point to Sensor, but the Sensors do not have pointers to their Captures, Cap --> Sen.

Wolf tree integrity ---------------------
Prb @ 0x55729d047f90
Hrw @ 0x55729d048160
  Sen2 @ 0x55729d0512d0
    -> Prb @ 0x55729d047f90
    -> Hrw @ 0x55729d048160
    O sb @ 0x55729d04a1a0 (lp @ 0x55729d04d870)
    P sb @ 0x55729d04b7e0
    Prc2 @ 0x55729d051890 -> Sen2
      -> Prb  @ 0x55729d047f90
      -> Sen2 @ 0x55729d0512d0
Trj @ 0x55729d048230
  Frm8 @ 0x55729d04c000
    -> Prb @ 0x55729d047f90
    -> Trj @ 0x55729d048230
    O sb @ 0x55729d056590 (lp @ 0x55729d04bef0)
    P sb @ 0x55729d04c170
    Cap10 @ 0x55729d04a2b0 -> Sen-
      -> Prb  @ 0x55729d047f90
      -> Frm8 @ 0x55729d04c000
      Ftr9 @ 0x55729d04ba70
        -> Prb  @ 0x55729d047f90
        -> Cap10 @ 0x55729d04a2b0
        Fac9 @ 0x55729d04b2f0 --> Abs.
          -> Prb  @ 0x55729d047f90
          -> Ftr9 @ 0x55729d04ba70
            sb @ 0x55729d056590 (lp @ 0x55729d04bef0) Frm8 found
      Ftr10 @ 0x55729d050010
        -> Prb  @ 0x55729d047f90
        -> Cap10 @ 0x55729d04a2b0
        Fac10 @ 0x55729d04c660 --> Abs.
          -> Prb  @ 0x55729d047f90
          -> Ftr10 @ 0x55729d050010
            sb @ 0x55729d04c170 Frm8 found
    Cap11 @ 0x55729d053ca0 -> Sen2
      -> Prb  @ 0x55729d047f90
      -> Frm8 @ 0x55729d04c000
Map @ 0x55729d048330
--------------------------- Wolf tree  OK